package me.sensen;

import javax.swing.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

/**
 * @author Sensen
 */
public class Services extends JFrame {

    private static boolean isProcessing = false;

    public Services() {
        JLabel jLabel = new JLabel("Put your file here");
        setTitle("Drop your setup file to sync to Upan and Local");
        setSize(400, 300);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jLabel.setHorizontalAlignment(SwingConstants.CENTER);
        add(jLabel);

        new DropTarget(this, new DropTargetListener() {
            @Override
            public void dragEnter(DropTargetDragEvent dtde) {
                if (!isProcessing) {
                    jLabel.setText("Free your file here");
                } else {
                    jLabel.setText("Processing! You can't drop your file here");
                }
            }

            @Override
            public void dragOver(DropTargetDragEvent dtde) {

            }

            @Override
            public void dropActionChanged(DropTargetDragEvent dtde) {

            }

            @Override
            public void dragExit(DropTargetEvent dte) {
                if (!isProcessing) {
                    jLabel.setText("Put your file here");
                } else {
                    jLabel.setText("Detect success,syncing...");
                }
            }

            @Override
            public void drop(DropTargetDropEvent dtde) {
                if (!isProcessing) {
                    jLabel.setText("Detect success,syncing...");
                    isProcessing = true;
                    try {
                        Transferable tr = dtde.getTransferable();
                        DataFlavor flavor = DataFlavor.javaFileListFlavor;
                        if (tr.isDataFlavorSupported(flavor)) {
                            dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
                            Object data = tr.getTransferData(flavor);
                            if (data instanceof List) {
                                List<?> list = (List<?>) data;
                                for (Object item : list) {
                                    if (item instanceof File) {
                                        File file = (File) item;
                                        System.out.println("Dropped file: " + file.getAbsolutePath());
                                        fileAction(jLabel,file);
                                    }
                                }
                            }
                            dtde.dropComplete(true);
                        } else {
                            dtde.rejectDrop();
                        }
                    } catch (Exception ex) {
                        ex.printStackTrace();
                        dtde.dropComplete(false);
                    }
                } else {
                    dtde.rejectDrop();
                }
            }
        });
    }

    public static void fileAction(JLabel jLabel, File file) {
        SwingWorker<Void, Integer> worker = new SwingWorker<Void, Integer>() {
            @Override
            protected Void doInBackground() throws Exception {
                Path sourcePath = file.toPath();
                Path targetPath1 = Paths.get(Main.localPath + "\\" + file.getName());
                Path targetPath2 = Paths.get(Main.UPanPath + "\\" + file.getName());

                try (FileInputStream fis = new FileInputStream(sourcePath.toFile());
                     FileOutputStream fos1 = new FileOutputStream(targetPath1.toFile());
                     FileOutputStream fos2 = new FileOutputStream(targetPath2.toFile())) {

                    long totalBytes = Files.size(sourcePath);
                    byte[] buffer = new byte[64 * 1024]; // 每次读取64 KB的数据
                    int bytesRead;
                    long bytesCopied = 0;

                    while ((bytesRead = fis.read(buffer)) != -1) {
                        // 将缓冲区内容写入到两个目标文件中
                        fos1.write(buffer, 0, bytesRead);
                        fos2.write(buffer, 0, bytesRead);
                        bytesCopied += bytesRead;

                        // 计算并发布复制进度
                        int progress = (int) ((bytesCopied * 100) / totalBytes);
                        publish(progress);
                    }
                } catch (IOException e) {
                    jLabel.setText("Failed to copy! error: " + e.getMessage());
                    isProcessing = false;
                }
                return null;
            }

            @Override
            protected void process(List<Integer> chunks) {
                // 更新 JLabel 显示进度
                int latestProgress = chunks.get(chunks.size() - 1);
                jLabel.setText("复制进度: " + latestProgress + "%");
            }

            @Override
            protected void done() {
                jLabel.setText("Success! You can go on or exit!");
                isProcessing = false;
            }
        };

        // 开始执行 SwingWorker
        worker.execute();
    }

}
